在 《 企業應用架構模式 》這本書中,它只有提到 MVC 這個它放在 Presentation 的模式,而接下來的幾篇文章的我們會多加了兩個模式分別為『 MVVM 』與 『 MVP 』,接下來這篇文章我們要好好的來理解,MVC 最原始的意思。
MVC 最早基本上應該是屬於 presentation,它主要聚焦在畫面根據 model 的互動,它最重要的概念在於將 UI 與 model 分離出來,它的組成如下 :
傳統上它後他們的關係如下圖,這裡應該會有人覺得很奇怪,為什麼 view 會與 model 有連結,應該有不少人使用是以 Backend 角度來想,那的確沒錯,因為例如 asp.net mvc 應該是 view → controller → model,而 model 不會與 view 有關係。
圖片來源: educative-Acing the JavaScript Design Patterns Interview
我當初看到這張圖有是有這想法,因此我去查了一下最原始的 MVC 出在《 A Description of the Model-View-Controller User Interface Paradigm in the Smalltalk-80 System 》這篇論文,它最原始的圖的確 model 會與 view 相互溝通,如下圖 :
圖片來源: 《 A Description of the Model-View-Controller User Interface Paradigm in the Smalltalk-80 System 》
我覺得有兩點,首先第一點在於『 傳統 MVC 應該是 view → controller → model,而 model 與 view 並不會有溝通 』,以 asp.net mvc 來看確是上面這樣,但我覺得當初會這樣做有兩個原因,第一點在於 web 中間多了個 http,而不像原始的 MVC 是設計上一般 gui 工具上。第二點當初我覺得 ASP.NET MVC 設計初宗是為了提現『 分離 』的概念。
然後第二點混亂點在於, 與我們上一篇文章提到的 3-Tier 搞混,MVC 是聚焦畫面與資料的互動模式,這也是為什麼 《 企業應用架構模式 》這本書作者會放在 presentation 層級,而 3-Tier 主要是聚焦在整個軟體架構上。
這些混亂的討論我覺得可以看一下,這篇文章的留言區,就會知道每個人的 MVC 真的完全不一樣。
https://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html
我這裡的範例,比較這張圖,因為原始論文 view 對 controller 的行為互動沒連線,但下面這張又缺了 model 對 controller 的變化通知,但論文裡的範例碼是有關係的。
圖片來源: educative-Acing the JavaScript Design Patterns Interview
主要分成三個部份 :
這裡有幾個重點要注意 :
const EventEmitter = require('events');
class UserView{
init(controller, model){
this.controller = controller
this.model = model
const that = this
this.model.on('model-change', () => {
that.updateView()
})
}
registerUser(name){
this.controller.registerUser(name)
}
updateView(){
console.log('Update user view !!!')
}
}
class UserListView{
init(controller, model){
this.controller = controller
this.model = model
const that = this
this.model.on('model-change', () => {
that.updateView()
})
}
updateView(){
console.log('Update user list view !!!')
}
}
class UserModel extends EventEmitter{
create(name){
console.log(`Create a user#${name}`)
this.emit('model-change')
}
}
class UserController{
init(userView, model){
this.view = userView
this.model = model
}
registerUser(name){
this.model.create(name)
}
}
const userModel = new UserModel()
const userView = new UserView()
const userListView = new UserListView()
const userController = new UserController()
userView.init(userController, userModel)
userListView.init(userController, userModel)
userController.init(userView, userModel)
userView.registerUser('Mark')
// Create a user#Mark
// Update user view !!!
// Update user list view !!!
這篇文章的範例是我主要根據最原始論文的內容,所撰寫的我自已覺得最初的概念是這樣的程式碼,不代表一定正確 ~ 請自行判斷 ~ 畢竟 MVC 這個內容如果你有認真去尋找相關資料,應該真的會很混亂 ~ 我也混亂很久,所以我才去找最原始版本的來看看 ~
MVC 會出來,我覺得最主要就是因為 SRP 單一職責原則,所提出的,定義好每部份 ( M、V、C ) 要做什麼事情。
ASP.NET MVC 我真一直以為最原始的 mvc 就是它的樣子,後來才發現它算是改良過的,不如說我覺得比較接近 MVP 啊。